#include "MainWindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QString>

MainWindow::MainWindow()
    : title_label(new QLabel("你画我猜 服务器", this))
    , tabs(new QTabWidget(this))
    , widget_layout(new QVBoxLayout(this))
    , addressPanel(new AddressPanel(this))
    , gamePanel(new GamePanel(this))
    , state_label(new QLabel(OFFLINE_TEXT, this))
    , state(State::Offline)
    , server(new QTcpServer(this))
{
    setWindowTitle(title_label->text());
    title_label->setAlignment(Qt::AlignCenter);
    state_label->setAlignment(Qt::AlignCenter);

    tabs->addTab(addressPanel, "网络面板");
    tabs->addTab(gamePanel, "游戏面板");

    widget_layout->addWidget(title_label);
    widget_layout->addWidget(tabs);
    widget_layout->addWidget(state_label);

    connect(addressPanel, SIGNAL(launched()), this, SLOT(onLaunched()));
    connect(addressPanel, SIGNAL(quited()), this, SLOT(onQuited()));
    connect(gamePanel, SIGNAL(started()), this, SLOT(onStarted()));
    connect(gamePanel, SIGNAL(finished()), this, SLOT(onFinished()));

    connect(server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}

void MainWindow::setState(State state)
{
    MainWindow::state = state;

    switch (state) {
    case State::Offline:
        state_label->setText(OFFLINE_TEXT);
        gamePanel->disable();
        break;
    case State::Waiting:
        state_label->setText(WAITING_TEXT);
        gamePanel->enable();
        break;
    case State::Running:
        state_label->setText(RUNNING_TEXT);
        gamePanel->disable(false);
        break;
    }
}

void MainWindow::onLaunched()
{
    auto pair = addressPanel->getAddress();
    server->listen(QHostAddress(pair.first), pair.second);
    setState(State::Waiting);
}

void MainWindow::onQuited()
{
    setState(State::Offline);
    broadcast("QUIT");
}

void MainWindow::onStarted()
{
    // 小于两人无法开始游戏
    if (players.size() < 2) {
        QMessageBox::critical(this, "错误", "人数少于两人！");
        gamePanel->onStartButtonClicked();
    } else {
        setState(State::Running);
        broadcast("START");
    }
}

void MainWindow::onFinished()
{
    setState(State::Waiting);
    broadcast("FINISH");
}

void MainWindow::onNewConnection()
{
    qDebug() << "onNewConnection";

    auto player = new Player(server->nextPendingConnection());

    connect(player, &Player::named, this, [=](auto name) {
        gamePanel->addPlayer(name);

        // 通知其他玩家有新玩家进入
        for (const auto& item : players) {
            if (player != item) {
                item->sendMessage(QString("JOIN %0").arg(name));
                player->sendMessage(QString("JOIN %0").arg(item->getName()));
            }
        }
    });

    connect(player, &Player::disconnected, this, [=]() {
        gamePanel->removePlayer(player->getName());
        players.removeAll(player);

        // 只剩1个人或者没人玩了
        if (players.size() <= 1) {
            broadcast("FINISH");
        } else {
            // 通知其他玩家有玩家离开
            broadcast(QString("LEAVE %0").arg(player->getName()));
        }
    });

    players.push_back(player);
    switch (state) {
    case State::Offline:
        break;
    case State::Waiting:
        player->sendMessage("INIT WAITING");
        break;
    case State::Running:
        player->sendMessage("INIT RUNNING");
        break;
    }
}

void MainWindow::broadcast(const QString& msg)
{
    for (const auto& item : players) {
        item->sendMessage(msg);
    }
}
